"""
数据库模型定义
"""
from sqlalchemy import Integer, String, Text, DateTime, create_engine, DECIMAL, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, sessionmaker, relationship
from datetime import datetime
from app.core.config import settings

class Base(DeclarativeBase):
    pass

class User(Base):
    """用户模型"""
    __tablename__ = "users"
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    user_id: Mapped[str] = mapped_column(String(50), unique=True, index=True, nullable=False)
    username: Mapped[str] = mapped_column(String(50), unique=True, index=True)
    email: Mapped[str] = mapped_column(String(100), unique=True, index=True)
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
    updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

class UserProfile(Base):
    """用户画像模型"""
    __tablename__ = "user_profiles"
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    user_id: Mapped[str] = mapped_column(String(50), unique=True, index=True, nullable=False)
    knowledge_level: Mapped[str] = mapped_column(String(20), default="beginner")  # beginner, intermediate, advanced
    learning_style: Mapped[str] = mapped_column(String(20), default="visual")     # visual, auditory, kinesthetic
    interests: Mapped[str] = mapped_column(Text)  # JSON格式存储兴趣列表
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
    updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

class UserProgress(Base):
    """用户学习进度模型"""
    __tablename__ = "user_progress"
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    user_id: Mapped[str] = mapped_column(String(50), index=True, nullable=False)
    subject: Mapped[str] = mapped_column(String(100), nullable=False)
    progress: Mapped[float] = mapped_column(DECIMAL(3, 2), default=0.00)  # 0.00 - 1.00
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
    updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    __table_args__ = (
        # 确保同一用户同一学科只有一个进度记录
        {'mysql_engine':'InnoDB'}
    )

class Document(Base):
    """文档模型"""
    __tablename__ = "documents"
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    title: Mapped[str] = mapped_column(String(200), nullable=False)
    content: Mapped[str] = mapped_column(Text, nullable=False)
    doc_type: Mapped[str] = mapped_column(String(20))  # text, pdf
    source: Mapped[str] = mapped_column(String(100))
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
    updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

class DocumentChunk(Base):
    """文档块模型"""
    __tablename__ = "document_chunks"
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    document_id: Mapped[int] = mapped_column(Integer, nullable=False)
    chunk_id: Mapped[str] = mapped_column(String(100), nullable=False)
    content: Mapped[str] = mapped_column(Text, nullable=False)
    source: Mapped[str] = mapped_column(String(200))
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

class Conversation(Base):
    """对话记录模型"""
    __tablename__ = "conversations"
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    user_id: Mapped[str] = mapped_column(String(50), index=True, nullable=False)
    question: Mapped[str] = mapped_column(Text, nullable=False)
    answer: Mapped[str] = mapped_column(Text, nullable=False)
    sources: Mapped[str] = mapped_column(Text)  # JSON格式存储来源信息
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

class KnowledgePoint(Base):
    """知识点模型"""
    __tablename__ = "knowledge_points"
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    subject: Mapped[str] = mapped_column(String(100), nullable=False, index=True)
    topic: Mapped[str] = mapped_column(String(200), nullable=False)
    description: Mapped[str] = mapped_column(Text)
    difficulty: Mapped[str] = mapped_column(String(20), default="medium")  # easy, medium, hard
    estimated_time: Mapped[int] = mapped_column(Integer)  # 预估学习时间（分钟）
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

class KnowledgePointRelation(Base):
    """知识点关系模型"""
    __tablename__ = "knowledge_point_relations"
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    from_point_id: Mapped[int] = mapped_column(Integer, ForeignKey("knowledge_points.id"), nullable=False)
    to_point_id: Mapped[int] = mapped_column(Integer, ForeignKey("knowledge_points.id"), nullable=False)
    relation_type: Mapped[str] = mapped_column(String(20), default="related")  # prerequisite, related, advanced
    weight: Mapped[float] = mapped_column(DECIMAL(3, 2), default=1.00)
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

class LearningResource(Base):
    """学习资源模型"""
    __tablename__ = "learning_resources"
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    point_id: Mapped[int] = mapped_column(Integer, ForeignKey("knowledge_points.id"), nullable=False)
    resource_type: Mapped[str] = mapped_column(String(20))  # video, article, exercise, project
    title: Mapped[str] = mapped_column(String(200), nullable=False)
    url: Mapped[str] = mapped_column(String(500))
    description: Mapped[str] = mapped_column(Text)
    estimated_time: Mapped[int] = mapped_column(Integer)  # 预估完成时间（分钟）

class LearningPath(Base):
    """学习路径模型"""
    __tablename__ = "learning_paths"
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    subject: Mapped[str] = mapped_column(String(100), nullable=False)
    name: Mapped[str] = mapped_column(String(200), nullable=False)
    description: Mapped[str] = mapped_column(Text)
    difficulty: Mapped[str] = mapped_column(String(20))  # beginner, intermediate, advanced
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

class LearningPathStage(Base):
    """学习路径阶段模型"""
    __tablename__ = "learning_path_stages"
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    learning_path_id: Mapped[int] = mapped_column(Integer, ForeignKey("learning_paths.id"), nullable=False)
    stage_order: Mapped[int] = mapped_column(Integer, nullable=False)
    topic: Mapped[str] = mapped_column(String(200), nullable=False)
    description: Mapped[str] = mapped_column(Text)
    estimated_time: Mapped[str] = mapped_column(String(50))
    resources: Mapped[str] = mapped_column(Text)  # JSON格式存储资源列表
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

class UserLearningPath(Base):
    """用户学习路径模型"""
    __tablename__ = "user_learning_paths"
    
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    user_id: Mapped[str] = mapped_column(String(50), nullable=False, index=True)
    learning_path_id: Mapped[int] = mapped_column(Integer, ForeignKey("learning_paths.id"), nullable=False)
    status: Mapped[str] = mapped_column(String(20), default="not_started")  # not_started, in_progress, completed
    current_stage: Mapped[int] = mapped_column(Integer, default=0)
    started_at: Mapped[datetime] = mapped_column(DateTime, nullable=True)
    completed_at: Mapped[datetime] = mapped_column(DateTime, nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

# 数据库连接URL
DATABASE_URL = f"mysql+mysqlconnector://{settings.MYSQL_USER}:{settings.MYSQL_PASSWORD}@{settings.MYSQL_HOST}:{settings.MYSQL_PORT}/{settings.MYSQL_DATABASE}"

# 创建数据库引擎
engine = create_engine(DATABASE_URL, echo=settings.DEBUG)

# 创建会话工厂
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

def get_db():
    """获取数据库会话"""
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()